package com.wy.office.swift.word.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.wy.office.swift.util.CollectionUtils;
import com.wy.office.swift.word.IWordConstants;

import lombok.Getter;
import lombok.Setter;

/**
 * office word中的for循环数据定义
 * 
 * @author wangyuan
 * @since 2019年3月19日
 */
@Getter
@Setter
public class WordForModel implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 8097812169418263951L;

    /**
     * 循环所在主体（表格、文本）
     */
    private String subject;
    /**
     * 循环方式（按行、按列）
     */
    private String way;
    /**
     * 循环组别名称
     */
    private String group;
    /**
     * 循环数据主体对应的键值，与{@link #data}中的每个元素集合数据一一对应
     */
    private List<String> keys;
    /**
     * 循环数据主体
     */
    private List<List<String>> data;

    public WordForModel(String subject, String way, String group) {
        super();
        this.subject = subject;
        this.way = way;
        this.group = group;
    }

    public WordForModel() {
        super();
    }
    
    /**
     * 获取此For结构中在word中设置的变量（带符号），形如：${for:row:group:key}
     * @return
     */
    public List<String> getSearchText() {
    	List<String> result = new ArrayList<>();
    	if(CollectionUtils.isEmpty(keys)) {
    		return result;
    	}
    	
    	StringBuilder sb = null;
    	for(String item : keys) {
    		sb = new StringBuilder();
    		sb.append(IWordConstants.VARIABLE_PREFIX);
    		sb.append(IWordConstants.FOR);
    		sb.append(IWordConstants.VARIABLE_SEPARATOR);
    		sb.append(way);
    		sb.append(IWordConstants.VARIABLE_SEPARATOR);
    		sb.append(group);
    		sb.append(IWordConstants.VARIABLE_SEPARATOR);
    		sb.append(item);
    		sb.append(IWordConstants.VARIABLE_SUFFIX);
    		
    		result.add(sb.toString());
    	}
    	
    	return result;
    }
    
    /**
     * 获取此For结构中在word中设置的变量（不带符号），形如：for:row:group:key
     * @return
     */
    public List<String> getOriginKey() {
    	List<String> result = new ArrayList<>();
    	if(CollectionUtils.isEmpty(keys)) {
    		return result;
    	}
    	
    	StringBuilder sb = null;
    	for(String item : keys) {
    		sb = new StringBuilder();
    		sb.append(IWordConstants.FOR);
    		sb.append(IWordConstants.VARIABLE_SEPARATOR);
    		sb.append(way);
    		sb.append(IWordConstants.VARIABLE_SEPARATOR);
    		sb.append(group);
    		sb.append(IWordConstants.VARIABLE_SEPARATOR);
    		sb.append(item);
    		
    		result.add(sb.toString());
    	}
    	
    	return result;
    }
    
    /**
     * 获取此For结构中，对于新增的行（列）在word中对应的键，带有索引，如果index=-1，则不会跟上索引号<br/>
     * 形如：{"for:row:group:key" : "${group:key[:index]}"}
     * @param index
     * @return
     */
    public Map<String, String> getKeyReplaceParam(int index) {
    	Map<String, String> result = new HashMap<>();
    	
    	StringBuilder keySb = null;
    	StringBuilder valueSb = null;
    	for(String item : keys) {
    		keySb = new StringBuilder();
    		keySb.append(IWordConstants.FOR);
    		keySb.append(IWordConstants.VARIABLE_SEPARATOR);
    		keySb.append(way);
    		keySb.append(IWordConstants.VARIABLE_SEPARATOR);
    		keySb.append(group);
    		keySb.append(IWordConstants.VARIABLE_SEPARATOR);
    		keySb.append(item);
    		
    		valueSb = new StringBuilder();
    		valueSb.append(IWordConstants.VARIABLE_PREFIX);
    		valueSb.append(group);
    		valueSb.append(IWordConstants.VARIABLE_SEPARATOR);
    		valueSb.append(item);
    		if(index != -1) {
    			valueSb.append(IWordConstants.VARIABLE_SEPARATOR);
        		valueSb.append(index);
    		}
    		valueSb.append(IWordConstants.VARIABLE_SUFFIX);
    		
    		result.put(keySb.toString(), valueSb.toString());
    	}
    	
    	return result;
    }
    
    /**
     * for循环解析之后对应的需要替换的键值对Map
     * @return
     */
    public Map<String, String> getDataReplaceParam() {
        final Map<String, String> result = new HashMap<>();
        if(CollectionUtils.isEmpty(data)){
            StringBuilder keySb = null;
            for(String item : keys) {
                keySb = new StringBuilder();
                keySb.append(group);
                keySb.append(IWordConstants.VARIABLE_SEPARATOR);
                keySb.append(item);
                
                result.put(keySb.toString(), "");
            }
        } else {
            List<String> list = null;
            
            for(int i = 0;i < data.size();i++){
                list = data.get(i);
                StringBuilder keySb = null;
                for(int j = 0;j < list.size();j++){
                    keySb = new StringBuilder();
                    keySb.append(group);
                    keySb.append(IWordConstants.VARIABLE_SEPARATOR);
                    keySb.append(keys.get(j));
                    keySb.append(IWordConstants.VARIABLE_SEPARATOR);
                    keySb.append(i);
                    
                    result.put(keySb.toString(), list.get(j));
                }
            }
        }
        
        return result;
    }
    
    public int dataSize() {
    	return CollectionUtils.isEmpty(data) ? 0 : data.size();
    }
    
    public void addKey(String key) {
        if(keys == null){
            keys = new ArrayList<>();
        }
        keys.add(key);
    }
    
    public void addAllKey(List<String> keys) {
        if(CollectionUtils.isEmpty(keys)){
            return;
        }
        
        if(this.keys == null){
            this.keys = new ArrayList<>();
        }
        
        this.keys.addAll(keys);
    }
    
    public void addData(List<String> data) {
        if(CollectionUtils.isEmpty(data)){
            return;
        }
        
        if(this.data == null){
            this.data = new ArrayList<>();
        }
        
        this.data.add(data);
    }
    
    public void addData(String... data) {
        if(data == null || data.length == 0){
            return;
        }
        
        List<String> dataItem = new ArrayList<>();
        for(String item : data){
            dataItem.add(item);
        }
        
        addData(dataItem);
    }

}
